package com.zjl.redis.第18章_五大数据类型和源码解析;

/**
 * 有这麽多 类型
 *      uintxx_t len; #SDS的长度，  因为 字符的  \0 是终止符，如果没有，则buf[] 就不能使用 \0 字符
 *      uintxx_t alloc; #用来计算 free 就是字符串已经分配的未使用的空间
 *      unsigned char flags #表示sds类型
 *      char buf[]; #实际存储
 *
 * Redis中字符串的实现, SDS有多种结构 (sds.h) :
 * sdshdr5、 (2^5 = 32byte) #测试用的，实际不用
 * sdshdr8、 (2^8 = 256byte)
 * sdshdr16、(2^16 = 65536byte = 64KB)
 * sdshdr32、(2^32 byte = 4GB)
 * sdshdr64、(2^64 byte = 17179869184G) 用于存储不同的长度的字符串。
 *
 * len表示SDS的长度，使我们在获取字符串长度的时候可以在0(1)情况下拿到，
 * 而不是像C那样需要遍历一遍字符串。
 * alloc可以用来计算 free 就是字符串已经分配的未使用的空间，
 *      有了这个值就可以引入预分配空间的算法了，而不用去考虑内存分配的问题。
 *
 * 内部为当前字符串实际分配的空间一般要高于实际字符串长度
 * 当字符串长度小于1M时,扩容都是"加倍"现有的空间,如果超过1M,
 * 扩容时每次只会多扩1M的空间。需要注意的是字符串最大长度为512M。
 *
 * 每个命令的执行，都是调用 t_string.c  里的命令
 * @see com.zjl.redis.第02章_十大数据类型.B1_String
 *      命令Command  这个方法  如：setCommand
 *
 * Redis启动时会预先建立10000个分别存储0~9999的redisObject变量作为共享对象，
 * 这就意味着如果set字符串的键值在  0~ 10000之间的话，
 * 则可以直接指向共享对象而不需要再建立新对象，此时键值不占空间!
 * 相当于java的常量池
 *
 * 在 redis中的 string类型中
 * RedisObject内部对应3大物理编码
 *      int     #如果 值太大（超出long [-9223372036854775808,9223372036854775807]范围），又会成为 "embstr"
 *      embstr  #浮点数也会保存成此类型  小于等于 44 字节字符串，内存紧凑，指针+1（o->ptr = sh+1;）直接在紧接着拼凑
 *              对于embstr,由于其实现是只读的，因此在对embstr对象进行修改时,都会先转化为raw再进行修改。
 *              因此，只要是修改embstr对象，修改后的对象一定是raw的，无论是否达到了44个字节
 *      raw     #大于 44 字节字符串，的值会单独在另外一个区域存储，不紧凑
 *
 */
public class B1_SDS动态字符串 {
    public static void main(String[] args) {
        System.out.println(Long.MAX_VALUE);
        System.out.println(Long.MIN_VALUE);
    }
}
